import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler, LabelEncoder
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
import matplotlib
import seaborn as sns

# 设置中文字体支持
matplotlib.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
matplotlib.rcParams['axes.unicode_minus'] = False

def load_and_preprocess_data():
    """
    加载并预处理数据
    """
    # 读取数据
    base = pd.read_csv('customer_base.csv')
    behavior = pd.read_csv('customer_behavior_assets.csv')
    
    # 获取最新的客户行为数据
    latest_behavior = behavior.sort_values('stat_month').groupby('customer_id').tail(1)
    
    # 合并数据
    merged = pd.merge(base, latest_behavior, on='customer_id', how='inner')
    
    return merged

def engineer_features(data):
    """
    特征工程
    """
    # 选择用于聚类的特征
    features_for_clustering = [
        'age', 'monthly_income', 'total_assets', 'deposit_balance', 
        'financial_balance', 'fund_balance', 'insurance_balance',
        'product_count', 'financial_repurchase_count', 
        'credit_card_monthly_expense', 'investment_monthly_count',
        'app_login_count', 'app_financial_view_time', 
        'app_product_compare_count'
    ]
    
    # 分类特征
    categorical_features = [
        'gender', 'occupation', 'occupation_type', 'lifecycle_stage',
        'marriage_status', 'city_level', 'branch_name', 'asset_level'
    ]
    
    # 处理数值特征
    numeric_data = data[features_for_clustering].fillna(0)
    
    # 处理分类特征 - 使用标签编码
    categorical_data = data[categorical_features].copy()
    label_encoders = {}
    
    for feature in categorical_features:
        le = LabelEncoder()
        categorical_data[feature] = le.fit_transform(categorical_data[feature].astype(str))
        label_encoders[feature] = le
    
    # 合并所有特征
    X = pd.concat([numeric_data, categorical_data], axis=1)
    
    return X, features_for_clustering, categorical_features

def perform_clustering(X, n_clusters=5):
    """
    执行聚类分析
    """
    # 数据标准化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X)
    
    # 执行K-means聚类
    kmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)
    cluster_labels = kmeans.fit_predict(X_scaled)
    
    return cluster_labels, kmeans, scaler

def analyze_clusters(data, cluster_labels, features_for_clustering, categorical_features):
    """
    分析聚类结果
    """
    # 添加聚类标签到原始数据
    data_with_clusters = data.copy()
    data_with_clusters['cluster'] = cluster_labels
    
    # 分析每个聚类的特征
    cluster_analysis = []
    
    for i in range(len(np.unique(cluster_labels))):
        cluster_data = data_with_clusters[data_with_clusters['cluster'] == i]
        cluster_info = {
            'cluster_id': i,
            'size': len(cluster_data),
            'percentage': len(cluster_data) / len(data_with_clusters) * 100
        }
        
        # 数值特征的平均值
        for feature in features_for_clustering:
            cluster_info[f'avg_{feature}'] = cluster_data[feature].mean()
        
        # 分类特征的众数
        for feature in categorical_features:
            cluster_info[f'mode_{feature}'] = cluster_data[feature].mode().iloc[0] if not cluster_data[feature].mode().empty else 'N/A'
        
        cluster_analysis.append(cluster_info)
    
    return pd.DataFrame(cluster_analysis), data_with_clusters

def visualize_clusters(X, cluster_labels, features_for_clustering):
    """
    可视化聚类结果
    """
    # 使用PCA降维到2D进行可视化
    scaler = StandardScaler()
    X_scaled = scaler.fit_transform(X[features_for_clustering])
    
    pca = PCA(n_components=2)
    X_pca = pca.fit_transform(X_scaled)
    
    # 绘制聚类结果
    plt.figure(figsize=(12, 8))
    scatter = plt.scatter(X_pca[:, 0], X_pca[:, 1], c=cluster_labels, cmap='viridis', alpha=0.6)
    plt.xlabel(f'PC1 ({pca.explained_variance_ratio_[0]:.2%} variance)')
    plt.ylabel(f'PC2 ({pca.explained_variance_ratio_[1]:.2%} variance)')
    plt.title('客户聚类结果 (PCA降维可视化)')
    plt.colorbar(scatter)
    
    # 添加聚类中心
    kmeans = KMeans(n_clusters=len(np.unique(cluster_labels)), random_state=42, n_init=10)
    kmeans.fit(X_pca)
    centers = kmeans.cluster_centers_
    plt.scatter(centers[:, 0], centers[:, 1], c='red', marker='x', s=200, linewidths=3, label='聚类中心')
    
    plt.legend()
    plt.tight_layout()
    plt.savefig('image_show/customer_clusters_visualization.png', dpi=300, bbox_inches='tight')
    plt.close()
    
    print("聚类结果可视化图表已保存到 customer_clusters_visualization.png")

def identify_customer_segments(cluster_analysis):
    """
    识别客户群体特征
    """
    print("\n=== 客户群体特征分析 ===")
    
    for _, cluster in cluster_analysis.iterrows():
        print(f"\n--- 群体 {cluster['cluster_id']} ---")
        print(f"客户数量: {cluster['size']} ({cluster['percentage']:.1f}%)")
        
        # 根据特征识别群体类型
        avg_assets = cluster['avg_total_assets']
        avg_income = cluster['avg_monthly_income']
        avg_repurchase = cluster['avg_financial_repurchase_count']
        avg_app_usage = cluster['avg_app_financial_view_time']
        
        # 简单的群体命名逻辑
        if avg_repurchase > cluster_analysis['avg_financial_repurchase_count'].median() * 1.5:
            segment_type = "高复购客户群体"
        elif avg_assets > cluster_analysis['avg_total_assets'].median() * 1.5:
            segment_type = "高资产客户群体"
        elif avg_income > cluster_analysis['avg_monthly_income'].median() * 1.5:
            segment_type = "高收入客户群体"
        elif avg_app_usage > cluster_analysis['avg_app_financial_view_time'].median() * 1.5:
            segment_type = "高活跃度客户群体"
        elif cluster['avg_age'] < 35:
            segment_type = "年轻客户群体"
        else:
            segment_type = "普通客户群体"
        
        print(f"群体类型: {segment_type}")
        print(f"平均总资产: {avg_assets:,.0f}")
        print(f"平均月收入: {avg_income:,.0f}")
        print(f"平均理财复购次数: {avg_repurchase:.2f}")
        print(f"平均APP理财浏览时长: {avg_app_usage:.2f}")

def main():
    """
    主函数
    """
    print("开始客户聚类分析...")
    
    # 加载数据
    print("1. 加载数据...")
    data = load_and_preprocess_data()
    print(f"数据加载完成，共 {len(data)} 条客户记录")
    
    # 特征工程
    print("2. 特征工程...")
    X, features_for_clustering, categorical_features = engineer_features(data)
    print(f"特征工程完成，共 {X.shape[1]} 个特征")
    
    # 聚类分析
    print("3. 执行聚类分析...")
    cluster_labels, kmeans, scaler = perform_clustering(X, n_clusters=5)
    print("聚类分析完成")
    
    # 分析聚类结果
    print("4. 分析聚类结果...")
    cluster_analysis, data_with_clusters = analyze_clusters(
        data, cluster_labels, features_for_clustering, categorical_features
    )
    
    # 显示聚类分析结果
    print("\n=== 聚类分析结果 ===")
    print(cluster_analysis[['cluster_id', 'size', 'percentage']].to_string(index=False))
    
    # 识别客户群体
    identify_customer_segments(cluster_analysis)
    
    # 可视化聚类结果
    print("5. 可视化聚类结果...")
    visualize_clusters(X, cluster_labels, features_for_clustering)
    
    # 保存带聚类标签的数据
    data_with_clusters.to_csv('image_show/customer_data_with_clusters.csv', index=False)
    print("带聚类标签的客户数据已保存到 customer_data_with_clusters.csv")
    
    # 保存聚类分析结果
    cluster_analysis.to_csv('image_show/cluster_analysis_results.csv', index=False)
    print("聚类分析结果已保存到 cluster_analysis_results.csv")
    
    print("\n客户聚类分析完成！")

if __name__ == '__main__':
    main()